﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;
using PPP.Model.FormatWrapper;
using PPP.Utils.Services;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing.Printing;
using System.Linq;
using System.Printing;
using System.Text;
using System.Threading.Tasks;

namespace PPP.ViewModel {
    /// <summary>
    /// Print ViewModel. Contains all printer settings.
    /// 
    /// <list type="bullet">
    /// <item>
    /// <term>Author</term>
    /// <description>Sebastian Will</description>
    /// </item>
    /// </list>
    /// 
    /// </summary>  
    public class PrintViewModel : ViewModelBase {

        #region Fields
        /// <summary>
        /// The list of page orientation formats.
        /// </summary>
        private ObservableCollection<PageOrientationFormatWrapper> _pageOrientationFormats = null;
        
        /// <summary>
        /// The list of available printers.
        /// </summary>
        private ObservableCollection<PrinterFormatWrapper> _availablePrinters = null;

        /// <summary>
        /// The selected printer.
        /// </summary>
        private PrinterFormatWrapper _selectedPrinter = null;

        /// <summary>
        /// The selected page orientation.
        /// </summary>
        private PageOrientationFormatWrapper _selectedPageOrientation = null;

        /// <summary>
        /// The selected paper size.
        /// </summary>
        private PaperSizeFormatWrapper _selectedPaperSize = null;

        #endregion

        #region Consts
        #region PropertyName Consts

        /// <summary>
        /// The <see cref="PageOrientationFormats" /> property's name.
        /// </summary>
        public const string PageOrientationFormatsPropertyName = "PageOrientationFormats";

        /// <summary>
        /// The <see cref="AvailablePrinters" /> property's name.
        /// </summary>
        public const string AvailablePrintersPropertyName = "AvailablePrinters";

        /// <summary>
        /// The <see cref="SelectedPrinter" /> property's name.
        /// </summary>
        public const string SelectedPrinterPropertyName = "SelectedPrinter";
        
        #endregion

        #region SettingName Consts

        /// <summary>
        /// The <see cref="PageOrientation" /> property's name.
        /// </summary>
        public const string PageOrientationSettingName = "PrinterPageOrientation";

        /// <summary>
        /// The <see cref="SelectedPrinter" /> property's name.
        /// </summary>
        public const string SelectedPrinterSettingName = "PrinterSelectedPrinter";

        /// <summary>
        /// The <see cref="SelectedPaperSize" /> property's name.
        /// </summary>
        public const string SelectedPaperSizeSettingName = "PrinterSelectedPaperSize";
        
        #endregion
        #endregion

        #region Properties

        /// <summary>
        /// The list of page orientation formats.
        /// </summary>
        public ObservableCollection<PageOrientationFormatWrapper> PageOrientationFormats {
            get {
                return _pageOrientationFormats == null ? _pageOrientationFormats = new ObservableCollection<PageOrientationFormatWrapper>() : _pageOrientationFormats;
            }
            set {
                if (_pageOrientationFormats == value)
                    return;
                _pageOrientationFormats = value;
                RaisePropertyChanged(PageOrientationFormatsPropertyName);
            }
        }

        /// <summary>
        /// The list of available printers.
        /// </summary>
        public ObservableCollection<PrinterFormatWrapper> AvailablePrinters {
            get {
                return _availablePrinters == null ? _availablePrinters = new ObservableCollection<PrinterFormatWrapper>() : _availablePrinters;
            }
            set {
                if (_availablePrinters == value)
                    return;
                _availablePrinters = value;
                RaisePropertyChanged(PageOrientationFormatsPropertyName);
            }
        }

        /// <summary>
        /// Gets or sets the page orientation.
        /// </summary>
        public PageOrientationFormatWrapper SelectedPageOrientation {
            get {
                return _selectedPageOrientation;
            }
            set {
                if (_selectedPageOrientation == value) return;
                _selectedPageOrientation = value;
                //RaisePropertyChanged(PageOrientationPropertyName);
                //Save Changes
                SettingsHandler.SetUserSettingParameter(PageOrientationSettingName, PrinterHandler.PageOrientationToString(value.PageOrientation));
            }
        }

        /// <summary>
        /// The selected paper size.
        /// </summary>
        public PaperSizeFormatWrapper SelectedPaperSize {
            get {
                return _selectedPaperSize;
            }
            set {
                if (_selectedPaperSize == value ||value == null)
                    return;
                _selectedPaperSize = value;
                SettingsHandler.SetUserSettingParameter(SelectedPaperSizeSettingName, value.Name);
            }
        }

        /// <summary>
        /// The selected printer.
        /// </summary>
        public PrinterFormatWrapper SelectedPrinter {
            get {
                return _selectedPrinter;
            }
            set {
                if (_selectedPrinter == value)
                    return;

                var oldValue = _selectedPrinter;
                _selectedPrinter = value;

                RaisePropertyChanged(SelectedPrinterPropertyName, oldValue, _selectedPrinter, true);
            }
        }

        #region Commands
        #endregion
        #endregion

        #region Constructors

        /// <summary>
        /// Constructor. Setup the default parameter.
        /// </summary>
        public PrintViewModel() {

            //Load PageOrientationFormats
            PageOrientationFormats.Add(new PageOrientationFormatWrapper(PageOrientation.Landscape));
            PageOrientationFormats.Add(new PageOrientationFormatWrapper(PageOrientation.Portrait));
            PageOrientationFormats.Add(new PageOrientationFormatWrapper(PageOrientation.Unknown));

            //Load AvailablePrinters
            foreach (string printer in PrinterSettings.InstalledPrinters) {
                AvailablePrinters.Add(new PrinterFormatWrapper(PrinterHandler.GetPrinterSettings(printer)));
            }

            //Select the default Printer
            PrinterFormatWrapper defaultPrinter = AvailablePrinters.SingleOrDefault(t => t.Name.Equals(PrinterHandler.GetDefaultPrinterSettings().PrinterName));
            if (defaultPrinter != null)
                SelectedPrinter = defaultPrinter;
            else
                SelectedPrinter = AvailablePrinters[0];

            //Select Landscape
            PageOrientationFormatWrapper defaultPageOrientation = PageOrientationFormats.SingleOrDefault(t => t.Name.Equals(SettingsHandler.GetPrinterPageOrientation()));
            if (defaultPageOrientation != null)
                SelectedPageOrientation = defaultPageOrientation;
            else
                SelectedPageOrientation = PageOrientationFormats[0];

            //Select Paper Size
            PaperSizeFormatWrapper defaultPaperSize = SelectedPrinter.PaperSizes.SingleOrDefault(t => t.Name.Equals(SettingsHandler.GetPrinterSelectedPaperSize()));
            if (defaultPaperSize != null)
                SelectedPaperSize = defaultPaperSize;
            else
                SelectedPaperSize = SelectedPrinter.PaperSizes[0];
        }

        #endregion

        #region Methods      

        #endregion

    }
}
